(* file : variable.ml
contains functions that are usefull to use variable
Arnaud Aujon   AUJA31018906
*)
open Type
open List
open Lexer

let env : (string * Type.vType) list ref = ref [] ;;

(* obj contains name of var which will be convert in object *)
let obj : string list ref = ref [] ;;


let var_id = ref 0 ;;

let get_new_name = function () -> incr var_id;
          ("Var__"^(string_of_int !var_id)) ;;

(*
error : string -> unit
print error message
*)
let error = function str -> print_string  str ; print_newline () ; exit 1
;;


let rec get_name_t1 var =
  match var with
    Var(name) -> name
  | Array_index(name, _) -> name
  | _ -> error "get_name error"
;;

let rec get_name_t2 var =
  match var with
    T2_Var(name) -> name
  | T2_Array_index(name, _) -> name
  | _ -> error "get_name error"
;;

let rec get_name_t3 var =
  match var with
    T3_Var(name) -> name
  | T3_Array_index(name, _) -> name
  | _ -> error "get_name error"
;;

let rec is_obj name =
  List.mem name !obj
;;

let t_is_obj t =
  match t with
    TObjVar(_) -> true
  | _ -> false
;;

(* get_var_int : string -> (string * expr) list
return value of variable in env or NotFound
*)
let rec get_var_int name vlist =
  match vlist with
    [] -> raise NotFound
  | (var2, value)::tail -> if (compare var2 name) == 0 then value 
                           else get_var_int name tail
;;

(* is_present : string -> bool
return true is variable is present in env
*)
let rec is_present name =
  (try let _ = get_var_int name !env in true
    with NotFound -> false)
;;

let rec get_var_type name = 
  (try get_var_int name !env
  with NotFound -> error ("get_var_type : unknown variable :"^name))
;;

let rec rm_var_int var env_list =
  match env_list with
    [] -> error ("rm_var_int : no var named `"^var^"`")
  | (name, t)::tail ->  if (compare name var == 0)
              then tail
              else (name,t)::(rm_var_int var tail)
;;

let rm_var var = 
  env := rm_var_int var !env
;;

let rec add_var value name  =
  if ( not (is_present name) )
    then env := (name, value)::!env
  else if (compare (String.uppercase name) name == 0 ) (*if it's a constant*)
    then error ("The variable `"^name^
              "` is a constant and can't be modified")
  

;;
